home *** CD-ROM | disk | FTP | other *** search
- #include "defs.h"
-
- /// "prototypes"
-
- Prototype void boopsi_BevelBox (struct BoopsiContext *, struct BoopsiDevice *, struct RastPort *rast, UWORD x, UWORD y, UWORD w, UWORD h, UWORD);
- Prototype BOOL boopsi_ClipDimensions (struct BoopsiContext *, UWORD, UWORD, UWORD *, UWORD *, UWORD *, UWORD *);
- Prototype struct BoopsiDevice *boopsi_CreateDeviceContext (struct Screen *screen, struct TextFont *font);
- Prototype ULONG boopsi_DISPOSE (struct BoopsiContext *, Class *, Object *, Msg);
- Prototype void boopsi_FreeDeviceContext (struct BoopsiDevice *device);
- Prototype __asm ULONG boopsi_GadgetDispatch (__A0 Class *, __A2 Object *, __A1 Msg);
- Prototype ULONG boopsi_GET (struct BoopsiContext *, Class *, Object *, struct opGet *);
- Prototype void boopsi_GetDimensions (struct BoopsiContext *, struct BoopsiGadget *, UWORD *, UWORD *, UWORD *, UWORD *);
- Prototype void boopsi_GetGhostingDimensions(struct BoopsiContext *, struct BoopsiGadget *, UWORD *, UWORD *, UWORD *, UWORD *);
- Prototype ULONG boopsi_GOACTIVE (struct BoopsiContext *, Class *, struct Gadget *, struct gpInput *);
- Prototype ULONG boopsi_GOINACTIVE (struct BoopsiContext *, Class *, struct Gadget *, struct gpGoInactive *);
- Prototype ULONG boopsi_HANDLEINPUT (struct BoopsiContext *, Class *, struct Gadget *, struct gpInput *);
- Prototype ULONG boopsi_HANDLEINPUT_Button (struct BoopsiContext *, struct BoopsiGadget *, struct Gadget *, struct gpInput *);
- Prototype ULONG boopsi_HANDLEINPUT_Popup (struct BoopsiContext *, struct BoopsiGadget *, struct Gadget *, struct gpInput *);
- Prototype BOOL boopsi_InsideBox (struct BoopsiContext *, struct BoopsiBox *, WORD, WORD);
- Prototype void boopsi_Line3D (struct BoopsiContext *, struct BoopsiDevice *, struct RastPort *, UWORD, UWORD, UWORD, UWORD);
- Prototype ULONG boopsi_NEW (struct BoopsiContext *, Class *, Object *, Msg);
- Prototype __stkargs void boopsi_Notify (struct BoopsiContext *, struct Gadget *, struct GadgetInfo *, ...);
- Prototype UWORD boopsi_RasterFit (struct BoopsiContext *, struct BoopsiDevice *, UBYTE *, UWORD, UWORD);
- Prototype LONG boopsi_RasterLength (struct BoopsiContext *, struct BoopsiDevice *, UBYTE *, UWORD);
- Prototype ULONG boopsi_RENDER (struct BoopsiContext *, Class *, struct Gadget *, struct gpRender *);
- Prototype void boopsi_RenderBackground (struct BoopsiContext *, struct BoopsiGadget *, struct Gadget *, struct GadgetInfo *, struct RastPort *);
- Prototype void boopsi_RenderButton (struct BoopsiContext *, struct BoopsiGadget *, struct Gadget *, struct GadgetInfo *, struct RastPort *);
- Prototype void boopsi_RenderDropbox (struct BoopsiContext *, struct BoopsiGadget *, struct Gadget *, struct GadgetInfo *, struct RastPort *);
- Prototype void boopsi_RenderFocus (struct BoopsiContext *, struct BoopsiGadget *, struct Gadget *, struct GadgetInfo *, struct RastPort *);
- Prototype void boopsi_RenderGadget (struct BoopsiContext *, struct BoopsiGadget *, struct Gadget *, struct GadgetInfo *, struct RastPort *);
- Prototype void boopsi_RenderGhosting (struct BoopsiContext *, struct BoopsiGadget *, struct Gadget *, struct GadgetInfo *, struct RastPort *);
- Prototype UWORD boopsi_RenderLabel (struct BoopsiContext *, struct BoopsiGadget *, struct RastPort *, UBYTE *, UWORD, UWORD, UWORD, UWORD, UWORD, UWORD);
- Prototype void boopsi_RenderPopupItem (struct BoopsiContext *, struct BoopsiGadget *, UWORD);
- Prototype void boopsi_RenderPopupWindow (struct BoopsiContext *, struct BoopsiGadget *);
- Prototype ULONG boopsi_SET (struct BoopsiContext *, Class *, struct Gadget *, struct opSet *);
- Prototype struct Window *boopsi_ShowPopupWindow (struct BoopsiContext *, struct BoopsiGadget *, struct Gadget *, struct GadgetInfo *);
-
- ///
- /// "support"
-
- /* ---------------------------- boopsi_CreateDeviceContext ---------------------
-
- Create device context
-
- */
-
- #define RGB_SHINE (213L<<24)
- #define RGB_SHADOW (120L<<24)
- #define RGB_GREY (120L<<24)
-
- struct BoopsiDevice *
- boopsi_CreateDeviceContext(struct Screen *screen, struct TextFont *font)
- {
- struct BoopsiDevice *device = NULL;
-
- if (screen && font)
- {
- struct DrawInfo *drawinfo;
-
- if (drawinfo = GetScreenDrawInfo(screen))
- {
- UWORD *pens = drawinfo->dri_Pens;
-
- if (device = (struct BoopsiDevice *)AllocVec(sizeof(struct BoopsiDevice), MEMF_PUBLIC | MEMF_CLEAR))
- {
- WORD *spacing;
- WORD *kerning;
- UWORD lochar;
- UWORD hichar;
- UWORD ascii;
- UWORD xwidth;
-
- device->Screen = screen;
- device->Font = font;
-
- // get font metrics
-
- lochar = (UWORD )font->tf_LoChar;
- hichar = (UWORD )font->tf_HiChar;
- spacing = (WORD *)font->tf_CharSpace;
- kerning = (WORD *)font->tf_CharKern;
-
- // get width of default glyph
-
- if (font->tf_Flags & FPF_PROPORTIONAL)
- xwidth = spacing[hichar - lochar + 1] + kerning[hichar - lochar + 1];
- else
- xwidth = font->tf_XSize;
-
- // build font spacing table
-
- for (ascii = 0; ascii < 256; ++ascii) {
-
- WORD width;
-
- if ((font->tf_Flags & FPF_PROPORTIONAL) && (ascii >= lochar) && (ascii <= hichar))
- width = spacing[ascii - lochar] + kerning[ascii - lochar];
- else
- width = xwidth;
-
- device->Spacing[ascii] = (width < 0) ? 0 : width;
- }
-
- // allocate pens
-
- device->PenBackground = pens[BACKGROUNDPEN];
- device->PenShine = pens[SHINEPEN ];
- device->PenShadow = pens[SHADOWPEN ];
-
- device->Pen3DShadow = ObtainBestPen(screen->ViewPort.ColorMap, RGB_SHADOW, RGB_SHADOW, RGB_SHADOW, OBP_Precision, PRECISION_EXACT, TAG_DONE);
-
- if (device->Pen3DShadow == -1)
- device->Pen3DShadow = pens[SHADOWPEN];
- else
- device->ReleasePen3DShadow = TRUE;
-
- device->Pen3DShine = ObtainBestPen(screen->ViewPort.ColorMap, RGB_SHINE, RGB_SHINE, RGB_SHINE, OBP_Precision, PRECISION_EXACT, TAG_DONE);
-
- if (device->Pen3DShine == -1)
- device->Pen3DShine = pens[SHINEPEN];
- else
- device->ReleasePen3DShine = TRUE;
-
- device->PenInactive = ObtainBestPen(screen->ViewPort.ColorMap, RGB_GREY, RGB_GREY, RGB_GREY, OBP_Precision, PRECISION_EXACT, TAG_DONE);
-
- if (device->PenInactive == device->PenBackground)
- {
- ReleasePen(screen->ViewPort.ColorMap, device->PenInactive);
-
- device->PenInactive = -1;
- }
-
- if (device->PenInactive == -1)
- device->PenInactive = pens[SHADOWPEN];
- else
- device->ReleasePenInactive = TRUE;
-
- }
-
- FreeScreenDrawInfo(screen, drawinfo);
- }
- }
-
- return(device);
- }
-
- /* ---------------------------- boopsi_FreeDeviceContext -----------------------
-
- Free device context
-
- */
-
- void
- boopsi_FreeDeviceContext(struct BoopsiDevice *device)
- {
- if (device)
- {
- if (device->Screen)
- {
- struct ColorMap *colormap = device->Screen->ViewPort.ColorMap;
-
- if (device->ReleasePen3DShadow)
-
- ReleasePen(colormap, device->Pen3DShadow);
-
- if (device->ReleasePen3DShine)
-
- ReleasePen(colormap, device->Pen3DShine);
-
- if (device->ReleasePenInactive)
-
- ReleasePen(colormap, device->PenInactive);
- }
-
- FreeVec(device);
- }
- }
-
- ///
- /// "dispatcher"
-
- /* ----------------------------- boopsi_GadgetDispatch -------------------------
-
- Class dispatcher (OS entry point)
-
- */
-
- __asm __saveds ULONG
- boopsi_GadgetDispatch(__A0 Class *class, __A2 Object *object, __A1 Msg msg)
- {
- struct BoopsiContext *context;
-
- if (context = (struct BoopsiContext *)class->cl_UserData)
- {
- ULONG retval;
-
- switch (msg->MethodID)
- {
- case OM_NEW:
-
- retval = boopsi_NEW(context, class, object, msg);
-
- break;
-
- case GM_HITTEST:
-
- retval = GMR_GADGETHIT;
-
- break;
-
- case GM_RENDER:
-
- retval = boopsi_RENDER(context, class, (struct Gadget *)object, (struct gpRender *)msg);
-
- break;
-
- case GM_GOACTIVE:
-
- retval = boopsi_GOACTIVE(context, class, (struct Gadget *)object, (struct gpInput *)msg);
-
- break;
-
- case GM_GOINACTIVE:
-
- retval = boopsi_GOINACTIVE(context, class, (struct Gadget *)object, (struct gpGoInactive *)msg);
-
- break;
-
- case GM_HANDLEINPUT:
-
- retval = boopsi_HANDLEINPUT(context, class, (struct Gadget *)object, (struct gpInput *)msg);
-
- break;
-
- case OM_UPDATE:
- case OM_SET:
-
- retval = boopsi_SET(context, class, (struct Gadget *)object, (struct opSet *)msg);
-
- break;
-
- case OM_GET:
-
- retval = boopsi_GET(context, class, object, (struct opGet *)msg);
-
- break;
-
- case OM_DISPOSE:
-
- retval = boopsi_DISPOSE(context, class, object, msg);
-
- break;
-
- default:
-
- retval = DoSuperMethodA(class, object, msg);
-
- break;
- }
-
- return(retval);
- }
- else
- return(GMR_NOREUSE);
- }
-
- ///
- /// "methods"
-
- /* ------------------------------ boopsi_NEW -----------------------------------
-
- NEW method
-
- */
-
- ULONG
- boopsi_NEW(struct BoopsiContext *context, Class *class, Object *object, Msg msg)
- {
- struct TagItem *tag;
- ULONG retval;
-
- retval = 0;
-
- if (tag = (struct TagItem *)((struct opSet *)msg)->ops_AttrList)
- {
- if (retval = (ULONG)DoSuperMethodA(class, object, msg))
- {
- struct BoopsiGadget *boopsigadget;
-
- if (boopsigadget = (struct BoopsiGadget *)INST_DATA(class, retval))
- {
- // parse tags
-
- while (tag->ti_Tag)
- {
- ULONG tagdata = tag->ti_Data;
-
- switch (tag->ti_Tag)
- {
- case BOOPSI_ATTRIB_DEVICE:
-
- boopsigadget->Device = (struct BoopsiDevice *)tagdata;
-
- break;
-
- case BOOPSI_ATTRIB_KIND:
-
- boopsigadget->Kind = tagdata;
-
- break;
-
- case GA_Top:
-
- boopsigadget->TopEdge = tagdata;
-
- break;
-
- case GA_Left:
-
- boopsigadget->LeftEdge = tagdata;
-
- break;
-
- case GA_Width:
-
- boopsigadget->Width = tagdata;
-
- break;
-
- case GA_Height:
-
- boopsigadget->Height = tagdata;
-
- break;
-
- case GA_Disabled:
-
- boopsigadget->Disabled = (BOOL)tagdata;
-
- break;
-
- case GTCY_Labels:
-
- if (boopsigadget->Labels = (UBYTE **)tagdata)
- {
- UBYTE **label;
-
- for (label = (UBYTE **)tagdata; *label; ++label)
-
- ++boopsigadget->Maximum;
- }
-
- break;
-
- case GTCY_Active:
-
- boopsigadget->Active = (LONG)tagdata;
-
- break;
-
- case BOOPSI_ATTRIB_PLACEMENT:
-
- boopsigadget->Placetext = tagdata;
-
- break;
-
- case BOOPSI_ATTRIB_FLAGS:
-
- boopsigadget->Flags = tagdata;
-
- break;
- }
-
- if (tag->ti_Tag == TAG_MORE)
- {
- tag = (struct TagItem *)tag->ti_Data;
- }
- else
- ++tag;
- }
-
- // request initial refresh (background is clear already, new gadgets never have the focus)
-
- if (boopsigadget->Kind && boopsigadget->Width && boopsigadget->Height && boopsigadget->Device && boopsigadget->Device->Screen && boopsigadget->Device->Font)
- {
- boopsigadget->Refresh = ~(BOOPSI_REFRESHBACKGROUND | BOOPSI_REFRESHFOCUS);
- }
- else
- retval = 0;
- }
- }
- }
-
- return(retval);
- }
-
- /* ---------------------------- boopsi_DISPOSE ---------------------------------
-
- DISPOSE method
-
- */
-
- ULONG
- boopsi_DISPOSE(struct BoopsiContext *context, Class *class, Object *object, Msg msg)
- {
- struct BoopsiGadget *boopsigadget = (struct BoopsiGadget *)INST_DATA(class, object);
-
- if (boopsigadget->Rectangles)
- {
- FreeVec(boopsigadget->Rectangles);
-
- boopsigadget->Rectangles = NULL;
- }
-
- return((ULONG)DoSuperMethodA(class, object, msg));
- }
-
- /* ----------------------------- boopsi_RENDER ---------------------------------
-
- RENDER method
-
- */
-
- ULONG
- boopsi_RENDER(struct BoopsiContext *context, Class *class, struct Gadget *gad, struct gpRender *gpr)
- {
- struct BoopsiGadget *boopsigadget = (struct BoopsiGadget *)INST_DATA(class, (Object *)gad);
-
- // full redraw required (to repair damage after coming to the front) ?
-
- if (gpr->gpr_Redraw == GREDRAW_REDRAW)
-
- if (gpr->gpr_GInfo->gi_Window->Flags & WFLG_SIMPLE_REFRESH)
-
- boopsigadget->Refresh = BOOPSI_REFRESHALL;
-
- boopsi_RenderGadget(context, boopsigadget, gad, gpr->gpr_GInfo, gpr->gpr_RPort);
-
- return(0);
- }
-
- /* ---------------------------- boopsi_GOACTIVE --------------------------------
-
- GOACTIVE method
-
- */
-
- ULONG
- boopsi_GOACTIVE(struct BoopsiContext *context, Class *class, struct Gadget *gad, struct gpInput *gpi)
- {
- ULONG retval = GMR_NOREUSE;
-
- if ((gad->Flags & GFLG_DISABLED) == FALSE)
- {
- struct BoopsiGadget *boopsigadget = (struct BoopsiGadget *)INST_DATA(class, (Object *)gad);
-
- switch (boopsigadget->Kind)
- {
- case BOOPSI_DROPBOX_KIND:
- case BOOPSI_BUTTON_KIND:
-
- retval = boopsi_HANDLEINPUT_Button(context, boopsigadget, gad, gpi);
-
- break;
- }
-
- // show focus
-
- if (retval == GMR_MEACTIVE)
- {
- boopsigadget->State |= BOOPSI_STATE_ACTIVE;
-
- boopsigadget->Refresh |= BOOPSI_REFRESHFOCUS;
- }
-
- // make visual update by calling own GM_RENDER method
-
- if (boopsigadget->Refresh)
-
- boopsi_RenderGadget(context, boopsigadget, gad, gpi->gpi_GInfo, NULL);
- }
-
- return(retval);
- }
-
- /* -------------------------- boopsi_HANDLEINPUT -------------------------------
-
- HANDLEINPUT method
-
- */
-
- ULONG
- boopsi_HANDLEINPUT(struct BoopsiContext *context, Class *class, struct Gadget *gad, struct gpInput *gpi)
- {
- struct BoopsiGadget *boopsigadget;
- ULONG retval;
-
- boopsigadget = (struct BoopsiGadget *)INST_DATA(class, (Object *)gad);
-
- switch (boopsigadget->Kind)
- {
- case BOOPSI_DROPBOX_KIND:
- case BOOPSI_BUTTON_KIND:
-
- retval = boopsi_HANDLEINPUT_Button(context, boopsigadget, gad, gpi);
-
- break;
-
- default:
-
- retval = GMR_MEACTIVE;
- }
-
- // make visual update by calling own GM_RENDER method
-
- if (boopsigadget->Refresh)
-
- boopsi_RenderGadget(context, boopsigadget, gad, gpi->gpi_GInfo, NULL);
-
- return(retval);
- }
-
- /* ------------------------------- boopsi_GOINACTIVE ---------------------------
-
- GOINACTIVE method
-
- */
-
- ULONG
- boopsi_GOINACTIVE(struct BoopsiContext *context, Class *class, struct Gadget *gad, struct gpGoInactive *gpgi)
- {
- struct BoopsiGadget *boopsigadget = (struct BoopsiGadget *)INST_DATA(class, (Object *)gad);
-
- // close popup window
-
- if (boopsigadget->Window)
- {
- CloseWindow(boopsigadget->Window);
-
- boopsigadget->Window = NULL;
- }
-
- // set gadget refresh
-
- switch (boopsigadget->Kind)
- {
- case BOOPSI_DROPBOX_KIND:
- case BOOPSI_BUTTON_KIND:
-
- boopsigadget->Refresh |= BOOPSI_REFRESHBUTTON;
-
- break;
- }
-
- // remove focus dashbox
-
- boopsigadget->State &= ~BOOPSI_STATE_ACTIVE;
-
- boopsigadget->Refresh |= BOOPSI_REFRESHFOCUS;
-
- boopsi_RenderGadget(context, boopsigadget, gad, gpgi->gpgi_GInfo, NULL);
-
- return(DoSuperMethodA(class, (Object *)gad, (Msg)gpgi));
- }
-
- /* ------------------------------ boopsi_SET -----------------------------------
-
- SET method
-
- */
-
- ULONG
- boopsi_SET(struct BoopsiContext *context, Class *class, struct Gadget *gad, struct opSet *ops)
- {
- struct TagItem tagarray[16];
-
- struct BoopsiGadget *boopsigadget;
- struct TagItem *tags;
- struct TagItem *tag;
- struct TagItem *supertag;
- ULONG retval;
-
- boopsigadget = (struct BoopsiGadget *)INST_DATA(class, (Object *)gad);
-
- // parse tag list with new attributes
-
- supertag = tagarray;
- tags = ops->ops_AttrList;
-
- while (tag = NextTagItem(&tags))
- {
- switch (tag->ti_Tag)
- {
- case GTCY_Active:
-
- if (boopsigadget->Active != tag->ti_Data)
- {
- boopsigadget->Active = tag->ti_Data;
-
- boopsigadget->Refresh |= BOOPSI_REFRESHACTIVE;
- }
-
- break;
-
- case GA_Disabled:
-
- if (tag->ti_Data ^ boopsigadget->Disabled)
- {
- boopsigadget->Disabled = (tag->ti_Data != FALSE);
-
- if (boopsigadget->Disabled)
- {
- gad->Flags |= GFLG_DISABLED;
-
- boopsigadget->Refresh |= BOOPSI_REFRESHGHOSTING;
- }
- else
- {
- gad->Flags &= ~GFLG_DISABLED;
-
- boopsigadget->Refresh |= BOOPSI_REFRESHALL;
- }
- }
-
- // fall through
-
- default:
-
- *supertag++ = *tag;
- }
- }
-
- // send tag list with superclass tags (if any) to superclass
-
- if (supertag != tagarray)
- {
- struct opSet superSet;
-
- superSet.MethodID = OM_SET;
- superSet.ops_GInfo = ops->ops_GInfo;
- superSet.ops_AttrList = tagarray;
-
- // terminate superclass tags
-
- supertag->ti_Tag = TAG_DONE;
-
- retval = DoSuperMethodA(class, (Object *)gad, (Msg)&superSet);
- }
- else
- retval = 0;
-
- // make visual update by calling own GM_RENDER method
-
- if (boopsigadget->Refresh)
- {
- struct RastPort *rast;
-
- if (rast = ObtainGIRPort(ops->ops_GInfo))
- {
- DoMethod((Object *)gad, GM_RENDER, ops->ops_GInfo, rast, GREDRAW_UPDATE);
-
- ReleaseGIRPort(rast);
- }
- }
-
- return(retval);
- }
-
- /* ------------------------------ boopsi_GET -----------------------------------
-
- GET method
-
- */
-
- ULONG
- boopsi_GET(struct BoopsiContext *context, Class *class, Object *object, struct opGet *opg)
- {
- struct BoopsiGadget *boopsigadget;
- ULONG retval;
-
- boopsigadget = (struct BoopsiGadget *)INST_DATA(class, object);
-
- switch (opg->opg_AttrID)
- {
- case GTCY_Active:
-
- *opg->opg_Storage = (ULONG)boopsigadget->Active;
-
- retval = TRUE;
-
- break;
-
- case GTCY_Labels:
-
- *opg->opg_Storage = (ULONG)boopsigadget->Labels;
-
- retval = TRUE;
-
- break;
-
- default:
-
- retval = DoSuperMethodA(class, object, (Msg)opg);
- }
-
- return(retval);
- }
-
- ///
- /// "button"
-
- /* ------------------------------ boopsi_HANDLEINPUT_Button -------------------
-
- Handle input for button gadget
-
- */
-
- ULONG
- boopsi_HANDLEINPUT_Button(struct BoopsiContext *context, struct BoopsiGadget *boopsigadget, struct Gadget *gad, struct gpInput *gpi)
- {
- ULONG retval = GMR_MEACTIVE;
-
- // pop-up window visible ?
-
- if (boopsigadget->State & BOOPSI_STATE_POPUP)
- {
- retval = boopsi_HANDLEINPUT_Popup(context, boopsigadget, gad, gpi);
-
- if (retval != GMR_MEACTIVE)
- {
- if (boopsigadget->Window)
- {
- CloseWindow(boopsigadget->Window);
-
- boopsigadget->Window = NULL;
- }
-
- // release and refresh button
-
- boopsigadget->State &= ~(BOOPSI_STATE_SELECTED | BOOPSI_STATE_POPUP);
-
- boopsigadget->Refresh |= BOOPSI_REFRESHBUTTON;
- }
- }
- else
- {
- struct InputEvent *ie;
-
- for (ie = gpi->gpi_IEvent; ie && (retval == GMR_MEACTIVE); ie = ie->ie_NextEvent)
- {
- switch (ie->ie_Class)
- {
- case IECLASS_RAWMOUSE:
-
- // pop-up menu assigned to button ?
-
- if (boopsigadget->Labels)
- {
- switch (ie->ie_Code)
- {
- case SELECTDOWN:
-
- boopsigadget->Selection = UNDEFINED;
-
- boopsi_ShowPopupWindow(context, boopsigadget, gad, gpi->gpi_GInfo);
-
- break;
-
- case SELECTUP:
-
- retval = GMR_NOREUSE;
-
- break;
- }
- }
- else
- {
- switch (ie->ie_Code)
- {
- case SELECTDOWN:
-
- boopsigadget->State |= BOOPSI_STATE_SELECTED;
-
- boopsigadget->Refresh |= BOOPSI_REFRESHBUTTON;
-
- if (boopsigadget->Flags & BOOPSI_FLAGS_GACTIMMEDIATE)
- {
- boopsi_Notify(context, gad, gpi->gpi_GInfo, BOOPSI_ATTRIB_ADDRESS, gad, TAG_DONE);
-
- retval = GMR_NOREUSE;
- }
-
- break;
-
- case SELECTUP:
-
- if ((boopsigadget->Flags & BOOPSI_FLAGS_GACTIMMEDIATE) == FALSE)
- {
- boopsi_Notify(context, gad, gpi->gpi_GInfo, BOOPSI_ATTRIB_ADDRESS, gad, TAG_DONE);
-
- retval = GMR_NOREUSE;
- }
-
- // release and refresh button
-
- boopsigadget->State &= ~(BOOPSI_STATE_SELECTED | BOOPSI_STATE_POPUP);
-
- boopsigadget->Refresh |= BOOPSI_REFRESHBUTTON;
-
- break;
- }
- }
-
- break;
- }
- }
- }
-
- return(retval);
- }
-
- ///
- /// "messages"
-
- /* --------------------------------- boopsi_Notify -----------------------------
-
- Send taglist to application (the app will receive it as IDCMP_IDCMPUPDATE
- message).
-
- */
-
- __stkargs void
- boopsi_Notify(struct BoopsiContext *context, struct Gadget *gad, struct GadgetInfo *gadInfo, ...)
- {
- struct TagItem *tags = (struct TagItem *)(&gadInfo + 1);
-
- DoMethod((Object *)gad, OM_NOTIFY, tags, gadInfo, 0);
- }
-
- ///
- /// "rendering"
-
- /* ------------------------------ RenderGadget ---------------------------------
-
- Render boopsigadget gadget (rast may be NULL).
-
- */
-
- void
- boopsi_RenderGadget(struct BoopsiContext *context, struct BoopsiGadget *boopsigadget, struct Gadget *gad, struct GadgetInfo *gadInfo, struct RastPort *rast)
- {
- if (boopsigadget->Refresh)
- {
- BOOL obtainGIRPort;
-
- if (obtainGIRPort = (rast == NULL))
-
- rast = ObtainGIRPort(gadInfo);
-
- if (rast)
- {
- SetFont(rast, boopsigadget->Device->Font);
-
- // erase focus
-
- if ((boopsigadget->State & BOOPSI_STATE_ACTIVE) == 0)
-
- boopsi_RenderFocus(context, boopsigadget, gad, gadInfo, rast);
-
- boopsi_RenderBackground(context, boopsigadget, gad, gadInfo, rast);
-
- switch (boopsigadget->Kind)
- {
- case BOOPSI_DROPBOX_KIND:
-
- boopsi_RenderDropbox(context, boopsigadget, gad, gadInfo, rast);
-
- break;
-
- case BOOPSI_BUTTON_KIND:
-
- boopsi_RenderButton(context, boopsigadget, gad, gadInfo, rast);
-
- break;
- }
-
- // show focus
-
- if (boopsigadget->State & BOOPSI_STATE_ACTIVE)
-
- boopsi_RenderFocus(context, boopsigadget, gad, gadInfo, rast);
-
- boopsi_RenderGhosting(context, boopsigadget, gad, gadInfo, rast);
-
- if (obtainGIRPort)
-
- ReleaseGIRPort(rast);
-
- // everything refreshed
-
- boopsigadget->Refresh = FALSE;
- }
- }
- }
-
-
- /* ----------------------------- boopsi_RenderFocus ----------------------------
-
- Render or erase focus dashbox
-
- */
-
- void
- boopsi_RenderFocus(struct BoopsiContext *context, struct BoopsiGadget *boopsigadget, struct Gadget *gad, struct GadgetInfo *gadInfo, struct RastPort *rast)
- {
- if (boopsigadget->Refresh & BOOPSI_REFRESHFOCUS)
- {
- if (boopsigadget->Flags & BOOPSI_FLAGS_CAPTUREFOCUS)
- {
- BOOL renderbox = boopsigadget->DashedW && boopsigadget->DashedH;
-
- if (renderbox)
- {
- if (boopsigadget->State & BOOPSI_STATE_ACTIVE)
- {
- boopsi_BevelBox(context, boopsigadget->Device, rast, boopsigadget->DashedX, boopsigadget->DashedY, boopsigadget->DashedW, boopsigadget->DashedH, BOOPSI_BEVELBOXMODE_THIN | BOOPSI_BEVELBOXMODE_DASHED);
- }
- else
- {
- boopsi_BevelBox(context, boopsigadget->Device, rast, boopsigadget->DashedX, boopsigadget->DashedY, boopsigadget->DashedW, boopsigadget->DashedH, BOOPSI_BEVELBOXMODE_THIN | BOOPSI_BEVELBOXMODE_ERASE);
-
- // repair ghosting
-
- if (boopsigadget->Disabled)
-
- boopsigadget->Refresh |= BOOPSI_REFRESHGHOSTING;
- }
- }
- }
-
- boopsigadget->Refresh &= ~BOOPSI_REFRESHFOCUS;
- }
- }
-
-
- /* -------------------------- boopsi_RenderBackground --------------------------
-
- Clear gadget background with color 0
-
- */
-
- void
- boopsi_RenderBackground(struct BoopsiContext *context, struct BoopsiGadget *boopsigadget, struct Gadget *gad, struct GadgetInfo *gadInfo, struct RastPort *rast)
- {
- if (boopsigadget->Refresh & BOOPSI_REFRESHBACKGROUND)
- {
- struct Window *win;
- UWORD x;
- UWORD y;
- UWORD w;
- UWORD h;
-
- boopsi_GetDimensions(context, boopsigadget, &x, &y, &w, &h);
-
- // clip at window borders
-
- win = gadInfo->gi_Window;
-
- if (boopsi_ClipDimensions(context, win->Width - 1 - win->BorderRight, win->Height - 1 - win->BorderBottom, &x, &y, &w, &h))
- {
- SetAPen(rast, boopsigadget->Device->PenBackground);
-
- RectFill(rast, x, y, x + w - 1, y + h - 1);
- }
-
- boopsigadget->Refresh &= ~BOOPSI_REFRESHBACKGROUND;
- }
- }
-
-
- /* -------------------------------- boopsi_RenderLabel -------------------------
-
- Render <label> at the specified position. You may pass in the width of a symbol
- to have it considered (the function will return the symbol position).
-
- */
-
- UWORD
- boopsi_RenderLabel(struct BoopsiContext *context, struct BoopsiGadget *boopsigadget, struct RastPort *rast, UBYTE *label, UWORD placement, UWORD left, UWORD top, UWORD width, UWORD height, UWORD symbolwidth)
- {
- UWORD imageX = left;
-
- if (label)
- {
- UWORD len;
-
- if (len = strlen(label))
- {
- UBYTE buffer[80];
-
- struct TextFont *font;
- UBYTE *underscore;
- UWORD labelsize;
- UWORD fontsize;
- UWORD x;
- UWORD y;
- UWORD lenA;
- UWORD lenB;
-
- // check underscore
-
- if (underscore = strchr(label, '_'))
- {
- // remove "_" from string
-
- --len;
-
- if (len > sizeof(buffer))
-
- len = sizeof(buffer);
-
- lenA = underscore - label;
-
- if (lenA > sizeof(buffer))
-
- lenA = sizeof(buffer);
-
- lenB = len - lenA;
-
- if (lenA)
-
- movmem(label, buffer, lenA);
-
- if (lenB)
-
- movmem(label + lenA + 1, buffer + lenA, lenB);
-
- label = buffer;
- }
-
- font = boopsigadget->Device->Font;
- fontsize = boopsigadget->Device->Font->tf_YSize;
-
- y = top + (height - fontsize + 1) / 2;
-
- // determine labelsize
-
- labelsize = boopsi_RasterLength(context, boopsigadget->Device, label, len);
-
- // calculate position
-
- switch (placement)
- {
- case PLACETEXT_IN:
-
- if (symbolwidth)
- {
- imageX = left + 2;
-
- x = imageX + symbolwidth + (width - symbolwidth - labelsize - 4) / 2;
- }
- else
- x = left + (width - labelsize) / 2;
-
- break;
-
- case PLACETEXT_LEFT:
-
- x = left - labelsize - 8;
-
- break;
-
- case PLACETEXT_ABOVE:
-
- x = left + (width - labelsize) / 2;
-
- y = top - font->tf_YSize - 4;
-
- break;
-
- case PLACETEXT_BELOW:
-
- x = left + (width - labelsize) / 2;
-
- y = top + height + 2;
-
- break;
-
- default:
-
- x = left + width + 7;
- }
-
- // dashbox not yet set ?
-
- if (boopsigadget->DashedW == 0)
- {
- boopsigadget->DashedX = x - 1;
- boopsigadget->DashedY = y - 1;
- boopsigadget->DashedW = labelsize + 2;
- boopsigadget->DashedH = fontsize + 2;
- }
-
- y += font->tf_Baseline;
-
- Move(rast, x, y);
-
- SetAPen(rast, boopsigadget->Device->PenShadow);
- SetBPen(rast, boopsigadget->Device->PenBackground);
-
- Text(rast, label, len);
-
- if (underscore)
- {
- labelsize = (lenA) ? boopsi_RasterLength(context, boopsigadget->Device, label, lenA) : 0;
-
- // move underscore down (if we have free rows below the baseline)
-
- switch (font->tf_YSize - font->tf_Baseline - 1)
- {
- case 0:
-
- break;
-
- case 1:
-
- ++y;
-
- break;
-
- default:
-
- y += 2;
-
- break;
- }
-
- // render underscore
-
- Move(rast, x + labelsize, y);
-
- Draw(rast, rast->cp_x + boopsigadget->Device->Spacing[*(underscore + 1)] - 1, y);
- }
- }
- }
-
- return(imageX);
- }
-
- /* ------------------------------ RenderGhosting -------------------------------
-
- Ghost gadget
-
- */
-
- void
- boopsi_RenderGhosting(struct BoopsiContext *context, struct BoopsiGadget *boopsigadget, struct Gadget *gad, struct GadgetInfo *gadInfo, struct RastPort *rast)
- {
- if (boopsigadget->Refresh & BOOPSI_REFRESHGHOSTING)
- {
- if (boopsigadget->Disabled)
- {
- static UWORD pattern[] = { 0x4444, 0x1111 };
-
- UWORD x, y, w, h;
-
- boopsi_GetGhostingDimensions(context, boopsigadget, &x, &y, &w, &h);
-
- // ghost gadget
-
- SetAfPt(rast, pattern, 1);
-
- SetDrMd(rast, JAM1);
-
- SetAPen(rast, 1);
-
- RectFill(rast, x, y, x + w - 1, y + h - 1);
-
- SetDrMd(rast, JAM2);
-
- SetAfPt(rast, NULL, 0);
- }
-
- boopsigadget->Refresh &= ~BOOPSI_REFRESHGHOSTING;
- }
- }
-
- /* ------------------------------- RenderDropbox -------------------------------
-
- Render dropbox
-
- */
-
- #define DROPBUTTONARROWWIDTH 16
-
- void
- boopsi_RenderDropbox(struct BoopsiContext *context, struct BoopsiGadget *boopsigadget, struct Gadget *gad, struct GadgetInfo *gadInfo, struct RastPort *rast)
- {
- if (boopsigadget->Refresh)
- {
- struct BoopsiDevice *device;
- UWORD x;
- UWORD y;
- UWORD w;
- UWORD h;
-
- device = boopsigadget->Device;
-
- // render label
-
- boopsi_GetDimensions(context, boopsigadget, &x, &y, &w, &h);
-
- if (boopsigadget->Refresh & BOOPSI_REFRESHLABEL)
- {
- boopsi_RenderLabel(context, boopsigadget, rast, (UBYTE *)gad->GadgetText, boopsigadget->Placetext, x, y, w, h, 0);
-
- boopsigadget->Refresh &= ~BOOPSI_REFRESHLABEL;
- }
-
- // render border
-
- if (boopsigadget->Refresh & BOOPSI_REFRESHDROPBOX)
- {
- static __chip UWORD planeptr[] = { 0xfe00, 0x7c00, 0x3800, 0x1000 };
-
- struct Image image;
-
- image.Width = 7;
- image.Height = 4;
- image.LeftEdge = (DROPBUTTONARROWWIDTH - 7) / 2;
- image.TopEdge = (h - 4) / 2;
- image.ImageData = planeptr;
- image.Depth = 1;
- image.PlanePick = 1;
- image.PlaneOnOff = 1;
- image.NextImage = NULL;
-
- // render separator line and arrow symbol
-
- boopsi_Line3D(context, device, rast, x + w - 2 - DROPBUTTONARROWWIDTH, y + 3, 0, h - 6);
-
- DrawImage(rast, &image, x + w - DROPBUTTONARROWWIDTH - 1, y);
-
- boopsigadget->Refresh &= ~BOOPSI_REFRESHDROPBOX;
- }
-
- // render active selection
-
- if (boopsigadget->Refresh & BOOPSI_REFRESHACTIVE)
- {
- // fill background
-
- SetAPen(rast, device->PenBackground);
-
- RectFill(rast, x + 2, y + 1, x + w - 3 - DROPBUTTONARROWWIDTH, y + h - 3);
-
- if (boopsigadget->Active < boopsigadget->Maximum)
- {
- UBYTE *label;
-
- if (label = boopsigadget->Labels[boopsigadget->Active])
- {
- UWORD len;
-
- if (len = strlen(label))
- {
- struct TextFont *font;
- UWORD indent;
- UWORD rasterfit;
-
- font = device->Font;
- indent = device->Spacing['x'];
-
- // render active selection inside available space
-
- rasterfit = (w - indent - DROPBUTTONARROWWIDTH - 2);
-
- if (len = boopsi_RasterFit(context, device, label, len, rasterfit))
- {
- ULONG rastersize;
- UWORD pen;
-
- rastersize = boopsi_RasterLength(context, device, label, len);
-
- // choose label color and style
-
- if (boopsigadget->Active)
- {
- SetSoftStyle(rast, FSF_BOLD, FSF_BOLD);
-
- pen = device->PenShadow;
- }
- else
- pen = device->PenInactive;
-
- SetAPen(rast, pen);
-
- SetBPen(rast, device->PenBackground);
-
- // render active entry
-
- Move(rast, x + indent + (rasterfit - rastersize) / 2, y + font->tf_Baseline + (boopsigadget->Height - font->tf_YSize) / 2);
-
- Text(rast, label, len);
-
- if (boopsigadget->Active)
-
- SetSoftStyle(rast, 0, FSF_BOLD);
- }
- }
- }
- }
-
- boopsigadget->Refresh &= ~BOOPSI_REFRESHACTIVE;
- }
-
- // render knob
-
- if (boopsigadget->Refresh & BOOPSI_REFRESHBUTTON)
- {
- UWORD appearance = (boopsigadget->State & BOOPSI_STATE_SELECTED) ? BOOPSI_BEVELBOXMODE_RECESSED : BOOPSI_BEVELBOXMODE_RAISED;
-
- boopsi_BevelBox(context, device, rast, x, y, w, h, appearance);
-
- boopsigadget->Refresh &= ~BOOPSI_REFRESHBUTTON;
- }
- }
- }
-
- /* ------------------------------- RenderButton --------------------------------
-
- Render button
-
- */
-
- void
- boopsi_RenderButton(struct BoopsiContext *context, struct BoopsiGadget *boopsigadget, struct Gadget *gad, struct GadgetInfo *gadInfo, struct RastPort *rast)
- {
- if (boopsigadget->Refresh)
- {
- struct BoopsiDevice *device;
- UWORD x;
- UWORD y;
- UWORD w;
- UWORD h;
-
- device = boopsigadget->Device;
-
- // render label
-
- boopsi_GetDimensions(context, boopsigadget, &x, &y, &w, &h);
-
- if (boopsigadget->Refresh & BOOPSI_REFRESHLABEL)
- {
- boopsi_RenderLabel(context, boopsigadget, rast, (UBYTE *)gad->GadgetText, boopsigadget->Placetext, x, y, w, h, 0);
-
- boopsigadget->Refresh &= ~BOOPSI_REFRESHLABEL;
- }
-
- // render knob
-
- if (boopsigadget->Refresh & BOOPSI_REFRESHBUTTON)
- {
- UWORD appearance = (boopsigadget->State & BOOPSI_STATE_SELECTED) ? BOOPSI_BEVELBOXMODE_RECESSED : BOOPSI_BEVELBOXMODE_RAISED;
-
- boopsi_BevelBox(context, device, rast, x, y, w, h, appearance);
-
- boopsigadget->Refresh &= ~BOOPSI_REFRESHBUTTON;
- }
- }
- }
-
- ///
- /// "popup"
-
- /* ----------------------------- boopsi_ShowPopupWindow ------------------------
-
- Show popup menu.
-
- */
-
- struct Window *
- boopsi_ShowPopupWindow(struct BoopsiContext *context, struct BoopsiGadget *boopsigadget, struct Gadget *gad, struct GadgetInfo *gadInfo)
- {
- // count menu entries
-
- boopsigadget->Entries = 0;
-
- if (boopsigadget->Labels)
- {
- UBYTE **next;
-
- for (next = boopsigadget->Labels; *next; ++next)
-
- ++boopsigadget->Entries;
-
- // allocate layout data
-
- if (boopsigadget->Entries)
- {
- if (boopsigadget->Rectangles = (struct Rectangle *)AllocVec(boopsigadget->Entries * sizeof(struct Rectangle), MEMF_PUBLIC))
- {
- UWORD items;
- UWORD itemheight;
- UWORD winwidth;
- UWORD winheight;
- UWORD columnsize;
- UWORD x;
- UWORD y;
-
- // select dropbox gadget (now)
-
- boopsigadget->State |= BOOPSI_STATE_SELECTED;
- boopsigadget->Refresh |= BOOPSI_REFRESHBUTTON;
-
- boopsi_RenderGadget(context, boopsigadget, gad, gadInfo, NULL);
-
- // layout menu
-
- itemheight = boopsigadget->Device->Font->tf_YSize + 3;
- columnsize = 0;
-
- x = 0;
- y = 0;
-
- #define MAX_LINES 13
-
- for (items = 0; items < boopsigadget->Entries; ++items)
- {
- UBYTE *label;
- UWORD len;
-
- // continue current column ?
-
- if (items % MAX_LINES)
- {
- y += itemheight;
- }
- else
- {
- x += SPACING_X + columnsize;
- y = SPACING_Y;
-
- columnsize = 0;
- }
-
- label = boopsigadget->Labels[items];
-
- if (len = strlen(label))
- {
- UWORD rastersize;
-
- if (rastersize = boopsi_RasterLength(context, boopsigadget->Device, label, len))
- {
- struct Rectangle *rectangle = &boopsigadget->Rectangles[items];
-
- rectangle->MinX = x;
- rectangle->MinY = y;
- rectangle->MaxX = x + rastersize - 1;
- rectangle->MaxY = y + itemheight - 1;
-
- if (columnsize < rastersize)
-
- columnsize = rastersize;
- }
- }
- }
-
- // layout window dimensions
-
- items = (boopsigadget->Entries < MAX_LINES) ? boopsigadget->Entries : MAX_LINES;
-
- winheight = SPACING_Y + items * itemheight + SPACING_Y;
-
- winwidth = SPACING_X + x + columnsize;
-
- if (winwidth < boopsigadget->Width)
-
- winwidth = boopsigadget->Width;
-
- // single-column menu ?
-
- if (boopsigadget->Entries <= MAX_LINES)
- {
- for (items = 0; items < boopsigadget->Entries; ++items)
-
- boopsigadget->Rectangles[items].MaxX = winwidth - SPACING_X;
- }
-
- // calculate popup window position
-
- x = gadInfo->gi_Domain.Left + boopsigadget->LeftEdge - (winwidth - boopsigadget->Width) / 2;
-
- y = gadInfo->gi_Domain.Top + boopsigadget->TopEdge + boopsigadget->Height;
-
- if (gadInfo->gi_Window)
- {
- x += gadInfo->gi_Window->LeftEdge;
-
- y += gadInfo->gi_Window->TopEdge;
- }
-
- // open popup window
-
- boopsigadget->Window = OpenWindowTags(NULL,
-
- WA_CustomScreen, boopsigadget->Device->Screen,
- WA_Left, x,
- WA_Top, y,
- WA_Width, winwidth,
- WA_Height, winheight,
- WA_Borderless, TRUE,
- WA_RMBTrap, TRUE,
- WA_Activate, FALSE,
- WA_Flags, 0,
- TAG_DONE
- );
-
- // render menu
-
- if (boopsigadget->Window)
- {
- SetFont(boopsigadget->Window->RPort, boopsigadget->Device->Font);
-
- boopsi_RenderPopupWindow(context, boopsigadget);
-
- boopsigadget->State |= BOOPSI_STATE_POPUP;
- }
- }
- }
- }
-
- return(boopsigadget->Window);
- }
-
- /* ------------------------------ RenderPopupWindow ----------------------------
-
- Render popup window
-
- */
-
- void
- boopsi_RenderPopupWindow(struct BoopsiContext *context, struct BoopsiGadget *boopsigadget)
- {
- struct Window *win;
-
- if (win = boopsigadget->Window)
- {
- struct RastPort *rast;
- UWORD n;
-
- rast = boopsigadget->Window->RPort;
-
- // fill background
-
- SetRast(rast, boopsigadget->Device->PenShine);
-
- // draw menu border
-
- SetAPen(rast, boopsigadget->Device->PenShadow);
-
- Move(rast, 0, 0);
- Draw(rast, win->Width - 1, 0);
- Draw(rast, win->Width - 1, win->Height - 1);
- Draw(rast, 0, win->Height - 1);
- Draw(rast, 0, 0);
-
- for (n = 0; n < boopsigadget->Entries; ++n)
-
- boopsi_RenderPopupItem(context, boopsigadget, n);
- }
- }
-
- /* ---------------------------- boopsi_RenderPopupItem -------------------------
-
- Render entry <n> of the popup menu
-
- */
-
- void
- boopsi_RenderPopupItem(struct BoopsiContext *context, struct BoopsiGadget *boopsigadget, UWORD n)
- {
- if (boopsigadget->Rectangles)
- {
- if (n < boopsigadget->Entries)
- {
- struct Window *win;
-
- if (win = boopsigadget->Window)
- {
- struct BoopsiDevice *device;
- struct RastPort *rast;
- struct Rectangle *rectangle;
- UBYTE *label;
- UWORD penA;
- UWORD penB;
-
- rast = win->RPort;
-
- // choose pens (rendering active entry ?)
-
- device = boopsigadget->Device;
-
- if (n == boopsigadget->Selection)
- {
- penA = device->PenShine;
- penB = device->PenShadow;
- }
- else
- {
- penA = device->PenShadow;
- penB = device->PenShine;
- }
-
- // fill background
-
- rectangle = &boopsigadget->Rectangles[n];
-
- SetAPen (rast, penB);
-
- RectFill(rast, rectangle->MinX, rectangle->MinY, rectangle->MaxX, rectangle->MaxY);
-
- // render label
-
- label = boopsigadget->Labels[n];
-
- if (label && *label)
- {
- SetAPen(rast, penA);
- SetBPen(rast, penB);
-
- Move(rast, rectangle->MinX, rectangle->MinY + device->Font->tf_Baseline);
-
- // grey out first entry ?
-
- if ((n != 0) && (boopsigadget->Flags & BOOPSI_FLAGS_FANCY))
- {
- SetSoftStyle(rast, FSF_BOLD, FSF_BOLD);
- }
-
- Text(rast, label, strlen(label));
-
- SetSoftStyle(rast, 0, FSF_BOLD);
- }
- }
- }
- }
- }
-
- /* ---------------------------------- boopsi_Line3D ----------------------------
-
- Draw a 3D-Line (either <height> or <width> is not 0).
-
- */
-
- void
- boopsi_Line3D(struct BoopsiContext *context, struct BoopsiDevice *device, struct RastPort *rast, UWORD xo, UWORD yo, UWORD width, UWORD height)
- {
- UWORD x1, y1;
-
- if (height)
- {
- x1 = xo;
- y1 = yo + height - 1;
- }
- else
- {
- x1 = xo + width - 1;
- y1 = yo;
- }
-
- SetAPen(rast, device->Pen3DShadow);
-
- Move(rast, xo, yo);
- Draw(rast, x1, y1);
-
- if ((device->Screen->RastPort.BitMap->Depth > 1) && (device->Pen3DShine != device->Pen3DShadow))
- {
- if (height)
- {
- ++xo;
- ++x1;
- }
- else
- {
- ++yo;
- ++y1;
- }
-
- SetAPen(rast, device->Pen3DShine);
-
- Move(rast, xo, yo);
- Draw(rast, x1, y1);
- }
- }
-
- /* --------------------------- boopsi_HANDLEINPUT_Popup ------------------------
-
- Handle input for popup window (HANDLEINPUT)
-
- */
-
- ULONG
- boopsi_HANDLEINPUT_Popup(struct BoopsiContext *context, struct BoopsiGadget *boopsigadget, struct Gadget *gad, struct gpInput *gpi)
- {
- struct InputEvent *ie;
- UWORD selection;
- ULONG retval;
-
- retval = GMR_MEACTIVE;
-
- selection = boopsigadget->Selection;
-
- // process user input
-
- for (ie = gpi->gpi_IEvent; ie && (retval == GMR_MEACTIVE); ie = ie->ie_NextEvent)
- {
- switch (ie->ie_Class)
- {
- case IECLASS_RAWMOUSE:
-
- {
- WORD x = boopsigadget->Window->MouseX;
- WORD y = boopsigadget->Window->MouseY;
-
- // locate item under mouse pointer
-
- selection = UNDEFINED;
-
- if (boopsigadget->Rectangles)
- {
- UWORD item;
-
- for (item = 0; item < boopsigadget->Entries; ++item)
- {
- struct Rectangle *rectangle = &boopsigadget->Rectangles[item];
-
- if ((x >= rectangle->MinX) && (y >= rectangle->MinY) && (x < rectangle->MaxX) && (y < rectangle->MaxY))
- {
- selection = item;
-
- break;
- }
- }
- }
-
- switch (ie->ie_Code)
- {
- case SELECTUP:
-
- // button released outside popup window ?
-
- if (boopsigadget->Selection == UNDEFINED)
- {
- retval = GMR_NOREUSE;
- }
- else
- {
- boopsigadget->Active = boopsigadget->Selection;
-
- switch (boopsigadget->Kind)
- {
- case BOOPSI_DROPBOX_KIND:
-
- boopsigadget->Refresh |= BOOPSI_REFRESHACTIVE;
-
- break;
- }
-
- boopsi_Notify(context, gad, gpi->gpi_GInfo, BOOPSI_ATTRIB_ADDRESS, gad, GTCY_Active, boopsigadget->Active, TAG_DONE);
-
- retval = GMR_NOREUSE;
- }
-
- break;
- }
- }
-
- break;
-
- case IECLASS_RAWKEY:
-
- switch (ie->ie_Code)
- {
- case CURSORDOWN:
-
- if (selection == UNDEFINED)
-
- selection = 0;
-
- else if ((selection + 1) < boopsigadget->Entries)
-
- ++selection;
-
- break;
-
- case CURSORUP:
-
- if (selection == UNDEFINED)
-
- selection = boopsigadget->Entries - 1;
-
- else if (selection)
-
- --selection;
-
- break;
-
- // ESC
-
- case 0x45:
-
- retval = GMR_NOREUSE;
-
- break;
-
- // SAPCE, TAB, CR, RETURN
-
- case 0x40:
- case 0x42:
- case 0x43:
- case 0x44:
-
- boopsigadget->Active = boopsigadget->Selection;
-
- boopsigadget->Refresh |= BOOPSI_REFRESHACTIVE;
-
- boopsi_Notify(context, gad, gpi->gpi_GInfo, BOOPSI_ATTRIB_ADDRESS, gad, GTCY_Active, boopsigadget->Active, TAG_DONE);
-
- retval = GMR_NOREUSE;
-
- break;
- }
-
- break;
- }
- }
-
- // highlight current selection, hide old selection
-
- if (selection != boopsigadget->Selection)
- {
- UWORD oldactive = boopsigadget->Selection;
-
- boopsigadget->Selection = selection;
-
- boopsi_RenderPopupItem(context, boopsigadget, selection);
-
- boopsi_RenderPopupItem(context, boopsigadget, oldactive);
- }
-
- return(retval);
- }
-
- ///
- /// "misc"
-
- /* --------------------------------- boopsi_BevelBox ---------------------------
-
- DrawBevelBox() replacement (thin lines, various styles)
-
- */
-
- void
- boopsi_BevelBox(struct BoopsiContext *context, struct BoopsiDevice *device, struct RastPort *rast, UWORD x, UWORD y, UWORD w, UWORD h, UWORD mode)
- {
- if (w--)
- {
- if (h--)
- {
- UWORD xp1, xp2, xp3, yp1, yp2, xpw, xpwm1, xpwm2, xpwm3, yph, yphm1, yphm2;
-
- // layout bevel box
-
- xp1 = x + 1;
- xp2 = xp1 + 1;
- xp3 = xp2 + 1;
-
- yp1 = y + 1;
- yp2 = yp1 + 1;
-
- xpw = x + w;
- xpwm1 = xpw - 1;
- xpwm2 = xpwm1 - 1;
- xpwm3 = xpwm2 - 1;
-
- yph = y + h;
- yphm1 = yph - 1;
- yphm2 = yphm1 - 1;
-
- if (mode & BOOPSI_BEVELBOXMODE_AMIGA)
- {
- SetAPen(rast, device->PenShine);
-
- RectFill(rast, x, y, x, yph);
-
- RectFill(rast, x, y, xpwm1, y);
-
- RectFill(rast, xp1, yp1, xp1, yphm1);
-
- RectFill(rast, xp3, yphm1, xpwm2, yphm1);
-
- RectFill(rast, xpwm2, yp1, xpwm2, yphm1);
-
- RectFill(rast, xpwm3, yp2, xpwm3, yphm2);
-
- SetAPen(rast, device->PenShadow);
-
- RectFill(rast, xp2, yp1, xp2, yphm1);
-
- RectFill(rast, xp2, yp1, xpwm3, yp1);
-
- RectFill(rast, xp1, yph, xpw, yph);
-
- RectFill(rast, xpw, y, xpw, yph);
-
- RectFill(rast, xpwm1, yp1, xpwm1, yphm1);
-
- RectFill(rast, xp3, yp1, xp3, yphm2);
- }
- else
- {
- static UWORD pattern[] = { 0xAAAA, 0x5555 };
-
- UWORD penShadow;
- UWORD penShine;
- UWORD penBackground;
-
- penShadow = device->PenShadow;
- penShine = device->PenShine;
- penBackground = device->PenBackground;
-
- if (mode & BOOPSI_BEVELBOXMODE_DASHED)
- {
- SetAfPt(rast, pattern, 1);
-
- SetBPen(rast, penBackground);
- }
-
- if (mode & BOOPSI_BEVELBOXMODE_ERASE)
- {
- SetAPen(rast, penBackground);
- }
- else if (mode & (BOOPSI_BEVELBOXMODE_SOLID | BOOPSI_BEVELBOXMODE_RECESSED | BOOPSI_BEVELBOXMODE_DASHED))
- {
- SetAPen(rast, penShadow);
- }
- else
- SetAPen(rast, penShine);
-
- RectFill(rast, x, y, x, yph);
-
- RectFill(rast, x, y, xpwm1, y);
-
- if ((mode & BOOPSI_BEVELBOXMODE_THIN) == 0)
-
- RectFill(rast, xp1, yp1, xp1, yphm1);
-
- if (mode & BOOPSI_BEVELBOXMODE_ERASE)
- {
- SetAPen(rast, penBackground);
- }
- else if (mode & (BOOPSI_BEVELBOXMODE_SOLID | BOOPSI_BEVELBOXMODE_RAISED | BOOPSI_BEVELBOXMODE_DASHED))
- {
- SetAPen(rast, penShadow);
- }
- else
- SetAPen(rast, penShine);
-
- RectFill(rast, xpw, y, xpw, yph);
-
- if ((mode & BOOPSI_BEVELBOXMODE_THIN) == 0)
-
- RectFill(rast, xpwm1, yp1, xpwm1, yph);
-
- RectFill(rast, xp1, yph, xpw, yph);
-
- if (mode & BOOPSI_BEVELBOXMODE_DASHED)
-
- SetAfPt(rast, NULL, 0);
- }
- }
- }
- }
-
- ///
- /// "metrics"
-
- /* --------------------------------- boopsi_InsideBox --------------------------
-
- Check whether (x|y) are indside the specified region
-
- */
-
- BOOL
- boopsi_InsideBox(struct BoopsiContext *context, struct BoopsiBox *box, WORD x, WORD y)
- {
- return((BOOL)((x >= box->Left) && (y >= box->Top) && (x < (box->Left + box->Width)) && (y < (box->Top + box->Height))));
- }
-
- /* --------------------------------- boopsi_GetDimensions ----------------------
-
- Return actual dimensions of gadget
-
- */
-
- void
- boopsi_GetDimensions(struct BoopsiContext *context, struct BoopsiGadget *boopsigadget, UWORD *x, UWORD *y, UWORD *w, UWORD *h)
- {
- *x = boopsigadget->LeftEdge;
- *y = boopsigadget->TopEdge;
- *w = boopsigadget->Width;
- *h = boopsigadget->Height;
- }
-
- /* ----------------------------- boopsi_GetGhostingDimensions ------------------
-
- Return dimensions of ghosting area
-
- */
-
- void
- boopsi_GetGhostingDimensions(struct BoopsiContext *context, struct BoopsiGadget *boopsigadget, UWORD *x, UWORD *y, UWORD *w, UWORD *h)
- {
- switch (boopsigadget->Kind)
- {
- case BOOPSI_DROPBOX_KIND:
- case BOOPSI_BUTTON_KIND:
-
- *x = boopsigadget->LeftEdge + 2;
- *y = boopsigadget->TopEdge + 1;
- *w = boopsigadget->Width - 4;
- *h = boopsigadget->Height - 3;
-
- break;
-
- default:
-
- *x = boopsigadget->LeftEdge;
- *y = boopsigadget->TopEdge;
- *w = boopsigadget->Width;
- *h = boopsigadget->Height;
-
- break;
- }
- }
-
- /* ----------------------------- boopsi_ClipDimensions -------------------------
-
- Clip dimensions of box (<x>, <y>, <w>, <h>) at <xmax> and <ymax>. Return TRUE
- if box is still visible.
-
- */
-
- BOOL
- boopsi_ClipDimensions(struct BoopsiContext *context, UWORD xmax, UWORD ymax, UWORD *x, UWORD *y, UWORD *w, UWORD *h)
- {
- if ((*x <= xmax) && (*y <= ymax))
- {
- if ((*x + *w - 1) > xmax)
-
- *w = xmax - *x;
-
- if ((*y + *h - 1) > ymax)
-
- *h = ymax - *y;
- }
- else
- {
- // fully obscured
-
- *w = 0;
- *h = 0;
- }
-
- if (*w && *h)
- return(TRUE);
- else
- return(FALSE);
- }
-
- /* ------------------------------- boopsi_RasterLength -------------------------
-
- Determine raster lenght of a string
-
- */
-
- LONG
- boopsi_RasterLength(struct BoopsiContext *context, struct BoopsiDevice *device, UBYTE *text, UWORD len)
- {
- LONG labelsize = 0;
-
- while (len--)
-
- labelsize += device->Spacing[*text++];
-
- return(labelsize);
- }
-
- /* --------------------------------- boopsi_RasterFit --------------------------
-
- Determine number of characters that will fit into given extent (<width>).
-
- */
-
- UWORD
- boopsi_RasterFit(struct BoopsiContext *context, struct BoopsiDevice *device, UBYTE *text, UWORD len, UWORD width)
- {
- LONG labelsize;
- UWORD count;
-
- for (count = 0, labelsize = 0; len--; ++count)
- {
- labelsize += device->Spacing[*text++];
-
- if (labelsize > width)
-
- return(count);
- }
-
- return(count);
- }
-
- ///
-